package com.itjin.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itjin.model.domain.dto.LearningMaterialUploadDTO;
import com.itjin.model.domain.dto.MaterialAuditDTO;
import com.itjin.model.domain.dto.MaterialBatchAuditDTO;
import com.itjin.model.domain.dto.StatDTO;
import com.itjin.model.domain.entity.LearningMaterial;
import com.itjin.model.domain.vo.LearningMaterialVO;
import com.itjin.model.result.Result;
import com.itjin.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;

/**
 * 文件管理控制器
 */
@RestController
@RequestMapping("/api/file")
@Tag(name = "文件管理", description = "文件上传下载和学习资料管理")
@Slf4j
public class FileController {

    @Resource
    private FileService fileService;

    // ==================== 用户端接口 ====================

    /**
     * 创建学习资料记录
     */
    @PostMapping("/learning-material/create")
    @Operation(summary = "创建学习资料记录", description = "用户通过文件URL创建学习资料记录，创建后进入待审核状态")
    public Result<LearningMaterialVO> createLearningMaterial(
            @Parameter(description = "资料信息") @Valid @RequestBody LearningMaterialUploadDTO uploadDTO) {
        
        log.info("用户创建学习资料: {}", uploadDTO.getTitle());
        return fileService.uploadLearningMaterial(uploadDTO);
    }

    /**
     * 修改学习资料信息（仅限待审核状态）
     */
    @PutMapping("/learning-material/{id}")
    @Operation(summary = "修改学习资料信息", description = "只能修改待审核状态的资料")
    public Result<Void> updateLearningMaterial(
            @Parameter(description = "资料ID") @PathVariable Integer id,
            @Parameter(description = "更新信息") @Valid @RequestBody LearningMaterialUploadDTO updateDTO) {
        
        log.info("用户修改学习资料: id={}, title={}", id, updateDTO.getTitle());
        return fileService.updateLearningMaterial(id, updateDTO);
    }

    /**
     * 删除学习资料（仅限待审核状态）
     */
    @DeleteMapping("/learning-material/{id}")
    @Operation(summary = "删除学习资料", description = "只能删除待审核状态的资料")
    public Result<Void> deleteLearningMaterial(
            @Parameter(description = "资料ID") @PathVariable Integer id) {
        
        log.info("用户删除学习资料: id={}", id);
        return fileService.deleteLearningMaterial(id);
    }

    /**
     * 分页查询公开的学习资料列表
     */
    @GetMapping("/learning-material/public")
    @Operation(summary = "分页查询公开学习资料", description = "查询已审核通过的学习资料列表，支持多种筛选和排序")
    public Result<Page<LearningMaterialVO>> getPublicMaterials(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "学院名称") @RequestParam(required = false) String collegeName,
            @Parameter(description = "学科分类") @RequestParam(required = false) String subjectType,
            @Parameter(description = "学年") @RequestParam(required = false) String academicYear,
            @Parameter(description = "学期") @RequestParam(required = false) Integer semester,
            @Parameter(description = "文件类型") @RequestParam(required = false) String fileType,
            @Parameter(description = "关键词搜索") @RequestParam(required = false) String keyword,
            @Parameter(description = "排序方式: download(下载量), view(浏览量), time(时间)") @RequestParam(defaultValue = "time") String orderBy) {
        
        return fileService.getPublicMaterials(current, size, collegeName, subjectType, 
                academicYear, semester, fileType, keyword, orderBy);
    }

    /**
     * 查询用户上传的资料列表
     */
    @GetMapping("/learning-material/my")
    @Operation(summary = "查询我的学习资料", description = "查询当前用户上传的所有资料")
    public Result<Page<LearningMaterial>> getUserMaterials(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) {
        
        return fileService.getUserMaterials(current, size);
    }

    /**
     * 查询用户待审核的资料列表
     */
    @GetMapping("/learning-material/pending")
    @Operation(summary = "查询我的待审核资料", description = "查询当前用户待审核状态的资料")
    public Result<Page<LearningMaterial>> getUserPendingMaterials(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) {
        
        return fileService.getUserPendingMaterials(current, size);
    }

    /**
     * 获取资料详情
     */
    @GetMapping("/learning-material/{id}")
    @Operation(summary = "获取学习资料详情", description = "获取学习资料详细信息，会增加浏览次数")
    public Result<LearningMaterialVO> getMaterialDetail(
            @Parameter(description = "资料ID") @PathVariable Integer id) {
        
        return fileService.getMaterialDetail(id);
    }

    /**
     * 下载资料
     */
    @GetMapping("/learning-material/{id}/download")
    @Operation(summary = "下载学习资料", description = "下载学习资料文件，会增加下载次数")
    public Result<String> downloadMaterial(
            @Parameter(description = "资料ID") @PathVariable Integer id) {
        
        log.info("用户下载学习资料: id={}", id);
        return fileService.downloadMaterial(id);
    }

    // ==================== 管理员接口 ====================

    /**
     * 管理员分页查询所有学习资料
     */
    @GetMapping("/admin/learning-material/list")
    @Operation(summary = "管理员查询所有学习资料", description = "管理员分页查询所有学习资料，支持审核状态筛选")
    public Result<Page<LearningMaterialVO>> getAdminMaterials(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "审核状态(0-待审核，1-通过，2-拒绝)") @RequestParam(required = false) Integer auditStatus,
            @Parameter(description = "学院名称") @RequestParam(required = false) String collegeName,
            @Parameter(description = "学科分类") @RequestParam(required = false) String subjectType,
            @Parameter(description = "上传者ID") @RequestParam(required = false) Integer uploaderId,
            @Parameter(description = "关键词搜索") @RequestParam(required = false) String keyword,
            @Parameter(description = "排序方式: audit_time(审核时间), download(下载量), view(浏览量), time(上传时间)") @RequestParam(defaultValue = "time") String orderBy) {
        
        return fileService.getAdminMaterials(current, size, auditStatus, collegeName, 
                subjectType, uploaderId, keyword, orderBy);
    }

    /**
     * 管理员查询待审核资料列表
     */
    @GetMapping("/admin/learning-material/pending")
    @Operation(summary = "管理员查询待审核资料", description = "管理员查询所有待审核的学习资料")
    public Result<Page<LearningMaterialVO>> getPendingAuditMaterials(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) {
        
        return fileService.getPendingAuditMaterials(current, size);
    }

    /**
     * 管理员审核单个资料
     */
    @PostMapping("/admin/learning-material/audit")
    @Operation(summary = "管理员审核资料", description = "管理员审核单个学习资料")
    public Result<Void> auditMaterial(
            @Parameter(description = "审核信息") @Valid @RequestBody MaterialAuditDTO auditDTO) {
        
        log.info("管理员审核资料: id={}, status={}", auditDTO.getMaterialId(), auditDTO.getAuditStatus());
        return fileService.auditMaterial(auditDTO);
    }

    /**
     * 管理员批量审核资料
     */
    @PostMapping("/admin/learning-material/batch-audit")
    @Operation(summary = "管理员批量审核资料", description = "管理员批量审核多个学习资料")
    public Result<Void> batchAuditMaterials(
            @Parameter(description = "批量审核信息") @Valid @RequestBody MaterialBatchAuditDTO batchAuditDTO) {
        
        log.info("管理员批量审核资料: 数量={}, status={}", batchAuditDTO.getMaterialIds().size(), batchAuditDTO.getAuditStatus());
        return fileService.batchAuditMaterials(batchAuditDTO);
    }

    /**
     * 管理员强制删除资料
     */
    @DeleteMapping("/admin/learning-material/{id}/force")
    @Operation(summary = "管理员强制删除资料", description = "管理员物理删除学习资料（不可恢复）")
    public Result<Void> forceDeleteMaterial(
            @Parameter(description = "资料ID") @PathVariable Integer id) {
        
        log.info("管理员强制删除资料: id={}", id);
        return fileService.forceDeleteMaterial(id);
    }

    /**
     * 管理员获取审核统计信息
     */
    @GetMapping("/admin/learning-material/audit-stats")
    @Operation(summary = "获取审核统计", description = "管理员获取各审核状态的资料数量统计")
    public Result<List<StatDTO>> getAuditStatistics() {
        return fileService.getAuditStatistics();
    }

    /**
     * 管理员获取每日上传统计
     */
    @GetMapping("/admin/learning-material/daily-upload-stats")
    @Operation(summary = "获取每日上传统计", description = "管理员获取最近30天的每日上传数量统计")
    public Result<List<StatDTO>> getDailyUploadStatistics() {
        return fileService.getDailyUploadStatistics();
    }

    /**
     * 管理员获取热门下载统计
     */
    @GetMapping("/admin/learning-material/top-download-stats")
    @Operation(summary = "获取热门下载统计", description = "管理员获取下载量最高的10个资料统计")
    public Result<List<StatDTO>> getTopDownloadStatistics() {
        return fileService.getTopDownloadStatistics();
    }

    // ==================== 公共接口 ====================

    /**
     * 获取学科分类列表（用于前端下拉选择）
     */
    @GetMapping("/learning-material/subjects")
    @Operation(summary = "获取学科分类列表", description = "获取所有可用的学科分类")
    public Result<String[]> getSubjectTypes() {
        String[] subjects = {
            "计算机科学与技术", "软件工程", "网络工程", "信息安全",
            "数学与应用数学", "统计学", "物理学", "化学",
            "英语", "汉语言文学", "历史学", "哲学",
            "经济学", "金融学", "会计学", "工商管理",
            "机械工程", "电气工程", "土木工程", "建筑学",
            "生物科学", "环境科学", "材料科学", "其他"
        };
        return Result.success(subjects);
    }

    /**
     * 获取学院列表（用于前端下拉选择）
     */
    @GetMapping("/learning-material/colleges")
    @Operation(summary = "获取学院列表", description = "获取所有可用的学院")
    public Result<String[]> getColleges() {
        String[] colleges = {
            "计算机科学与技术学院", "软件学院", "信息工程学院",
            "数学与统计学院", "物理与电子学院", "化学与材料学院",
            "文学院", "外国语学院", "历史文化学院",
            "经济管理学院", "商学院", "法学院",
            "机械工程学院", "电气工程学院", "土木建筑学院",
            "生命科学学院", "环境科学学院", "其他学院"
        };
        return Result.success(colleges);
    }

    /**
     * 获取学年列表（用于前端下拉选择）
     */
    @GetMapping("/learning-material/academic-years")
    @Operation(summary = "获取学年列表", description = "获取所有可用的学年")
    public Result<String[]> getAcademicYears() {
        String[] years = {
            "2024-2025", "2023-2024", "2022-2023", "2021-2022", 
            "2020-2021", "2019-2020", "2018-2019", "其他"
        };
        return Result.success(years);
    }
}
